﻿/*
   Open Intel 
   Copyright © 2011 – ISC. All Rights Reserved.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using Caliburn.Micro;
using OI.Async;
using OI.DataModel;
using OI.Events;

namespace OI.Framework
{
    [Export(typeof(SharingManager))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class SharingManager : IHandle<SaveStateRequest>, IHandle<RestoreStateRequest>
    {
        readonly private IEventAggregator Events;
        public Dictionary<string, string> State = new Dictionary<string, string>();


        [ImportingConstructor]
        public SharingManager(IEventAggregator events)
        {
            events.Subscribe(this);
            Events = events;
        }


        // request that the SharingManager begin a save
        public void Handle(SaveStateRequest message)
        {
            State.Clear();

            // collect state from all subscribers
            Events.Publish(new SaveState
            {
                Write = State.Add
            });

            // save state to cloud via service
            string stateStr = MessageSerializer.Serialize(State);
             Coroutine.BeginExecute(SaveStateAsync(message.ID, stateStr, message.PostSave));
        }


        // request that the SharingManager begin a restore
        public void Handle(RestoreStateRequest message)
        {
             Coroutine.BeginExecute(RestoreStateAsync(message.ID, message.PostRestore));
        }


        public IEnumerator<IResult> SaveStateAsync(Guid id, string state, System.Action postSave)
        {
            Events.Publish(new ShowBusy { Caption = "saving state to share..." });

            var ss = new SharingServiceWrite(id, state);
            yield return ss;

            Events.Publish(new HideBusy());

            if (postSave != null)
            {
                postSave();
            }
        }


        public IEnumerator<IResult> RestoreStateAsync(Guid id, System.Action postRestore)
        {
            Events.Publish(new ShowBusy { Caption = "restoring state from share..." });

            var ss = new SharingServiceRead(id);
            yield return ss;

            Events.Publish(new HideBusy());
            string stateStr = ss.Results;

            // deserialize state and publish request to update
            if (!string.IsNullOrEmpty(stateStr))
            {
                var stateBag = MessageSerializer.Deserialize<Dictionary<string, string>>(stateStr);
                Events.Publish(new RestoreState
                {
                    Read = (key) => stateBag[key]
                });
            }

            if (postRestore != null)
            {
                postRestore();
            }
        }
    }
}
